package com.webssh.service.controller;

import com.jcraft.jsch.JSchException;
import com.webssh.service.handler.terminal.Terminal;
import com.webssh.service.handler.terminal.TerminalClient;
import com.webssh.service.handler.terminal.TerminalSession;
import com.webssh.service.util.WebUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *  
 * @author zhanshuw
 *     	   2018年6月21日
 * 
 */
@Controller
public class TerminalController {

	private static Logger logger = LoggerFactory.getLogger(TerminalController.class);
    
    @RequestMapping(value = "static/terminal/login.do")
    @ResponseBody
    public Map<String, Object> login(HttpSession session, Terminal terminal) throws Exception {
    	Map<String, Object> map = new HashMap<>();
    	 if (StringUtils.isEmpty(terminal.getHost()) 
    			 || terminal.getPort() == 0
    			 || StringUtils.isEmpty(terminal.getUserName())
    			 || StringUtils.isEmpty(terminal.getPassword())
    			 ) {
             return map;
         }
    	 try {
			new TerminalClient(terminal).init(session.getId());
			map.put("name", terminal.getName() + "(" + terminal.getHost() + ")");
			map.put("status", "success");
		 } catch (JSchException e) {
			 map.put("status", "failure");
			 map.put("msg", "失败：" + e.getMessage());
		 }
         return map;
    }

    @RequestMapping("terminal/open.htm")
    public String open(HttpServletRequest request, HttpSession session) throws Exception {
    	Terminal t = TerminalSession.findConnectedTerminalClient(session.getId());
    	if (t != null) {
    		logger.debug("该会话已有登陆成功链接，直接链接ssh");
    		request.setAttribute("windowTitle", t.getName() + "(" + t.getHost() + ")");
    		Terminal tt = t.copy();
    		tt.setPassword(null);
    		request.setAttribute("terminal", tt);
    	}else{
    		setRequestTerminal(request);
    	}
    	return "console";
    }
    @RequestMapping("terminal/openNew.htm")
    public String openNew(HttpServletRequest request, HttpSession session) throws Exception {
    	request.setAttribute("openNew", true);
    	setRequestTerminal(request);
    	return "console";
    }
    
    private void setRequestTerminal(HttpServletRequest request){
    	Terminal terminal = new Terminal();
    	terminal.setName("Terminal");
    	terminal.setHost("127.0.0.1");
    	terminal.setPort(22);
        terminal.setUserName(System.getProperty("user.name"));
        request.setAttribute("terminal", terminal);
    }

    @RequestMapping(value = "terminal/upload.do",method= RequestMethod.POST)
    public void upload(String token, HttpServletResponse response, HttpSession session,
    		@RequestParam(value = "file", required = false) MultipartFile[] file, String path) throws IOException {
        TerminalClient terminalClient = null;
        if(StringUtils.isNotEmpty(token)){
        	List<TerminalClient> list = TerminalSession.findClient(session.getId());
        	for(TerminalClient t: list){
        		if(token.equals(t.getUploadFileToken())){
        			terminalClient = t;
        			break;
        		}
        	}
        }
        boolean success = true;
        String msg = "";
		if (terminalClient != null) {
            for (MultipartFile ifile : file) {
            	InputStream in = null;
                try {
                	in = ifile.getInputStream();
                    if (StringUtils.isBlank(path)) {
                        path = ".";
                    } else {
                        if (path.endsWith("/")) {
                            path = path.substring(0, path.lastIndexOf("/"));
                        }
                    }
                    terminalClient.upload(in, path + "/" + ifile.getOriginalFilename(), ifile.getSize());
                } catch (Exception e) {
                	logger.error(e.getMessage(), e);
                    success = false;
                    msg = e.getMessage();
                }finally {
                	if(in != null){
                		in.close();
                	}
				}
            }
        }else{
        	success = false;
        	msg = "链接已断开";
        }
        WebUtils.writeJson(response, String.format("{\"success\":\"%s\", \"msg\":\"%s\"}", success ? "true" : "false", msg));
    }
    
    @RequestMapping(value = "terminal/download.do")
    public void download(String token, final HttpServletResponse response, HttpSession session, 
    		String path) throws IOException {
    	TerminalClient terminalClient = null;
    	if(StringUtils.isNotEmpty(token)){
    		List<TerminalClient> list = TerminalSession.findClient(session.getId());
    		for(TerminalClient t: list){
    			if(token.equals(t.getUploadFileToken())){
    				terminalClient = t;
    				break;
    			}
    		}
    	}
    	boolean success = false;
    	String msg = "";
    	if (terminalClient != null) {
    		if(StringUtils.isBlank(path)){
    			msg = "文件不能空";
    		}else{
    	        try {
    	        	final String name = path.substring(path.lastIndexOf("/") + 1);
    	        	if (!path.startsWith("/")) {
                        path = "./" + path;
                    }
    				terminalClient.get(new TerminalClient.WriteData(){
						@Override
						public void writeDate(InputStream in, long fileSize) throws IOException {
							response.setHeader("Cache-Control", "private");
							response.setHeader("Pragma", "private");
							response.setContentType("application/octet-stream;charset=utf-8");
							response.setHeader("Content-Type", "application/force-download");
							response.setHeader("Content-Disposition", "attachment;filename=" + name);
							response.setHeader("Content-Length", "" + fileSize);
//							response.setContentLengthLong(fileSize);
							int i = 0;
							byte[] b = new byte[1024];
							while((i = in.read(b)) >= 0){
								response.getOutputStream().write(b, 0, i);
							}
						}
    				}, path);
    				success = true;
    			} catch (Exception e) {
    				msg = "ERROR:" + e.getMessage();
    				logger.error(msg, e);
    			}
    		}
    	}else{
    		msg = "链接已断开";
    	}
    	if(!success){
    		WebUtils.writeJson(response, msg);
    	}
    }
}